package edu.mtu.citizenscience.cs.utils;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import edu.mtu.citizenscience.cs.utils.exceptions.NoExternalWrite;

import android.content.Context;
import android.media.MediaRecorder;
/**
 * @author Corbin Uselton <corbinu@cwuselto@mtu.edu>
 * @copyright (c) 2012 MichiganTech <http://www.mtu.edu>
 * @since 1.0
 * 
 * Holds utilities for interacting with audio
 */
public class Audio {
	// holds media recording when it is being used by an activity
	private static MediaRecorder MEDIA_RECORDER;
	
	/**
	 * Starts a new recording for the appName passed until the recorder is unloaded
	 * 
	 * @param   context - Context - The activity doing the recording
	 * @param	appName - String - The name of the app recording
	 * @return	File - the file that the audio is being recorded to
	 * @throws NoExternalWrite
	 * @throws IllegalStateException
	 * @throws IOException
	 */
	public static File record(Context context, String appName) throws NoExternalWrite, IllegalStateException, IOException
	{
		// Make sure that there is writable storage to write the audio to
		if (Utils.isExternalStorageWritable())
		{
			// get dir to save the file to in the standard citsci files location plus the app name and audio
			File audioDir = new File(Utils.citsciFiles(context), appName + "/audio/");
			// make sure the audio dir and its parent dirs exist
			audioDir.mkdirs();
				
			// create a new file in the audio dir named for the current date-time plus m4a
			File audioFile = new File(audioDir,  new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()) + ".m4a");
			
			// create a new media recorder
			MEDIA_RECORDER = new MediaRecorder();
			// set the audio source to the devices main mic
			MEDIA_RECORDER.setAudioSource(MediaRecorder.AudioSource.MIC);
			// set the format to MEPG4
			MEDIA_RECORDER.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
			// set the encoder to AAC
			MEDIA_RECORDER.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
			// set the output file to the new audio file
			MEDIA_RECORDER.setOutputFile(audioFile.getAbsolutePath());
			// prepare the recorder
	        MEDIA_RECORDER.prepare();
	        // start recording
	        MEDIA_RECORDER.start();
		        
	        // return the file the audio is being recored to
		    return audioFile;
		}
		else
		{
			// since cannot write to the external files throw an exception
			throw new NoExternalWrite();
		}
	}
	
	/**
	 * Releases the media recorder if it is attached
	 * 
	 * @param   void
	 * @return	void
	 */
    public static void unloadRecorder()
    {
    	// if the MediaRecorder is attached
    	if (MEDIA_RECORDER != null)
    	{
    		// release tand reset the recorder
    		MEDIA_RECORDER.stop();
    		MEDIA_RECORDER.reset();
    		MEDIA_RECORDER.release();
    		
    		// set the recorder to null
			MEDIA_RECORDER = null;
    	}
    }
}
